//=============================================================================
///	I/O
/**

Functions:
	open
	close
	read-line
	read-char

*/
//=============================================================================

#include "mio.h"
#include "mlisp.h"
#include "sstream.h"
#include "ssym.h"
#include "senv.h"


//=============================================================================
// subr

static SExp subr_open(int narg, SExp args[]) {
	SExp sfn = type_check(args[0], tString);
	const char* fn = sfn.ptr->string.str;
	char* mode;
	if (narg >= 2) {
		SExp smode = type_check(args[1], tString);
		mode = smode.ptr->string.str;
	} else {
		mode = "r";
	}
	{
		FILE* fp = fopen(fn, mode);
		if (fp == NULL) {
			return nil;
		} else {
			return make_file_stream(fp, fn);
		}
	}
}

static SExp subr_close(int narg, SExp args[]) {
	if (close_stream(args[0])) {
		return t;
	} else {
		return nil;
	}
}

static SExp subr_read_line(int narg, SExp args[]) {
	SExp sstrm = (narg >= 1) ? args[0] : sstdin;
	return read_line(sstrm);
}

static SExp subr_read_char(int narg, SExp args[]) {
	SExp sstrm = (narg >= 1) ? args[0] : sstdin;
	SExp r = read_char(sstrm);
//	if (nilp(r)) {
//		// do something...
//	}
	return r;
}


//=============================================================================

void define_io_module(void) {
	struct {
		const char* name;
		SubrType cfunc;
		int minargnum, maxargnum;
	} subr_tbl[] = {
		{	"open",			subr_open,		1,	2,	},
		{	"close",		subr_close,		1,	1,	},
		{	"read-line",	subr_read_line,	0,	1,	},
		{	"read-char",	subr_read_char,	0,	1,	},
	};
	int i;
	for (i=0; i<sizeof(subr_tbl)/sizeof(*subr_tbl); ++i) {
		SExp subr = gen_subr(subr_tbl[i].cfunc, subr_tbl[i].name, subr_tbl[i].minargnum, subr_tbl[i].maxargnum);
		SExp sym = intern(subr_tbl[i].name);
		setq(sym, subr);
	}
}

